package com.star.core.config;

import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 返回数据格式化
 *
 * @author yangzj
 */
@Configuration
public class DataFormatConfig {

    public static final String DATA_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATA_FORMAT = "yyyy-MM-dd";


    /**
     * post请求 对象 入参空字符转null
     *
     * @return {@link SimpleModule}
     */
    @Bean
    public SimpleModule simpleModule() {
        return new SimpleModule().addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
                return "".equals(jsonParser.getValueAsString()) ? null : jsonParser.getValueAsString();
            }
        });
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        // 出参
        return builder -> builder
                .serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATA_TIME_FORMAT)))
                .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATA_TIME_FORMAT)))
                .serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DATA_FORMAT)))
                .deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DATA_FORMAT)))
                .serializerByType(Date.class, new DateSerializer(null, new SimpleDateFormat(DATA_TIME_FORMAT)))
                .serializerByType(Long.class, ToStringSerializer.instance)
                .serializerByType(Long.TYPE, ToStringSerializer.instance)
                /// 出参 空字符串转null
                /*.serializerByType(String.class, new ToStringSerializerBase(String.class) {
                    @Override
                    public String valueToString(Object o) {
                        return "".equals(o) ? null : o.toString();
                    }
                })*/;
    }

    @Bean
    public StringToLocalDateTimeConverter localDateTimeConverter() {
        return c -> LocalDateTime.parse(c, DateTimeFormatter.ofPattern(DATA_TIME_FORMAT));
    }

    interface StringToLocalDateTimeConverter extends Converter<String, LocalDateTime> {
    }

    @Bean
    public StringToLocalDateConverter localDateConverter() {
        return c -> LocalDate.parse(c, DateTimeFormatter.ofPattern(DATA_FORMAT));
    }

    interface StringToLocalDateConverter extends Converter<String, LocalDate> {
    }

    @Bean
    public StringToDateConverter dateConverter() {
        return c -> DateUtil.parse(c, DATA_TIME_FORMAT);
    }

    interface StringToDateConverter extends Converter<String, Date> {
    }

    /**
     * get请求 入参 空字符串转null
     *
     * @return {@link StringToNullConverter}
     */
    @Bean
    public StringToNullConverter stringToNullConverter() {
        return c -> "".equals(c) ? null : c;
    }

    interface StringToNullConverter extends Converter<String, String> {
    }
}
